'use strict';

const Service = require('egg').Service;
const CryptoJS = require("crypto-js");
const sequelize = require('sequelize').Sequelize;
const Op = sequelize.Op;

class UserService extends Service {

  async add(request) {
    let { mobile, idCard, role } = request;
    const { User } = this.ctx.model;

    const userEx = await User.findOne({
      where: {
        accountName: mobile
      }
    });

    if (userEx) { this.ctx.throw(400, "当前手机号已注册！"); }

    let password = idCard.substring(idCard.length - 6, idCard.length);

    password = CryptoJS.AES.encrypt(password, this.config.keys, { iv: 0, mode: CryptoJS.mode.CBC }).toString();

    let user = {
      accountName: mobile,
      password,
      nickName: 'default',
      headImgUrl: '/public/default_user.jpeg',
      role,
      mobile,
      idCard,
      createDate: new Date(),
      createBy: this.ctx.state.user.id
    }

    const retUser = await User.create(user);

    return {
      result: true
    }
  }

  async login(accountName, password) {
    const { User } = this.ctx.model;
    const user = await User.findOne({
      where: {
        accountName
      }
    });

    if (!user) {
      this.ctx.throw(403, '用户名不存在！')
    }

    let user_password = CryptoJS.AES.decrypt(user.password, this.config.keys, { iv: 0, mode: CryptoJS.mode.CBC }).toString(CryptoJS.enc.Utf8);

    if (password != user_password) {
      this.ctx.throw(403, '密码错误！')
    }

    let token = CryptoJS.AES.encrypt(
      `${user.id}||${user.accountName}||${user.nickName}||${user.role}||${new Date().getTime() + 30 * 60 * 1000}`,
      this.config.keys,
      { iv: 0, mode: CryptoJS.mode.CBC }).toString()

    this.ctx.setToken(token)

    return token;

  }

  async get(id) {
    const { User } = this.ctx.model;
    let user = await User.findOne({
      where: {
        id
      }
    });

    if (!user) {
      this.ctx.throw(404, '用户名不存在！')
    }

    let returnUser = JSON.parse(JSON.stringify(user.dataValues))
    delete returnUser.password;
    delete returnUser.accountnName;

    return returnUser;
  }

  async list(pageNo, pageSize, filter) {
    const { User } = this.ctx.model;

    const offset = pageSize * (pageNo - 1);
    const limit = pageSize;
    const order = [["create_date", "desc"]];

    const attributes = [
      ["id", "id"],
      ["nick_name", "nickName"],
      ["head_img_url", "headImgUrl"],
      ["location", "location"],
      ["id_card", "idCard"],
      ["mobile", "mobile"],
      ["email", "email"],
      ["create_date", "createDate"]
    ];

    const users = await User.findAndCountAll({
      where: filter, attributes, limit, offset, order
    });

    let hasNextPage = pageNo * pageSize < users.count;

    let result = {
      totalCount: users.count,
      pageNo,
      pageSize,
      users: users.rows,
      hasNextPage,
    };

    return result;
  }

  async update(request) {
    const { User } = this.ctx.model;
    let user = await User.findOne({
      where: {
        id: request.id
      }
    });

    if (!user) {
      this.ctx.throw(404, '用户不存在！')
    }

    user.nickName = request.nickName;
    user.headImgUrl = request.headImgUrl;
    user.location = request.location;
    user.idCard = request.idCard;
    user.mobile = request.mobile;
    user.email = request.email;
    user.updateDate = new Date();
    user.updateBy = this.ctx.state.user.id;
    await user.save();

    return {
      result: true
    };

  }

  async delete(id) {
    const { User, LendedInfo } = this.ctx.model;
    let user = await User.findOne({
      where: {
        id
      }
    });

    if (!user) {
      this.ctx.throw(404, '用户不存在！')
    }

    const lendedInfo = await LendedInfo.findOne({
      where: {
        [Op.and]: {
          userId: id,
          actualReturnDate: {
            [Op.is]: null,
          }
        }
      }
    });

    if (lendedInfo) {
      this.ctx.throw(400, '当前用户有未归还书籍，删除失败！')
    }
    await User.findOne({
      where: {
        id
      }
    });

    return {
      result: true
    };

  }

  async reset(request) {
    const { id } = request;
    const { User } = this.ctx.model;
    let user = await User.findOne({
      where: {
        id
      }
    });

    if(!user){
      this.ctx.throw(404, '用户不存在！')
    }

    let password = user.idCard.substring(user.idCard.length - 6, user.idCard.length);

    user.password = CryptoJS.AES.encrypt(password, this.config.keys, { iv: 0, mode: CryptoJS.mode.CBC }).toString();
    user.updateDate = new Date();
    user.updateBy = this.ctx.state.user.id;
    await user.save()
    return {
      result: true
    };
  }

  async changePassword(request) {
    const { newPassword,oldPassword } = request;
    const {id} = this.ctx.state.user;
    const { User } = this.ctx.model;
    let user = await User.findOne({
      where: {
        id
      }
    });

    if(!user){
      this.ctx.throw(404, '用户不存在！')
    }

    let user_password = CryptoJS.AES.decrypt(user.password, this.config.keys, { iv: 0, mode: CryptoJS.mode.CBC }).toString(CryptoJS.enc.Utf8);
    if(oldPassword!=user_password){
      this.ctx.throw(400, '旧密码错误，请重新输入！');
    }

    user.password = CryptoJS.AES.encrypt(newPassword, this.config.keys, { iv: 0, mode: CryptoJS.mode.CBC }).toString();
    user.updateDate = new Date();
    user.updateBy = id;
    await user.save()
    return {
      result: true
    };
  }
}
module.exports = UserService;
